#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "data.h"

int width = 0;
int height = 0;

//change the status of a cell with arguments - grid, i, j and flag
//check grid, i, j, flag
//return 0 if successfully, otherwise return 1
int changeCell(char *cells, int i, int j, char flag)
{
    if( flag != '0' && flag!= '1'){
        return 1;
    }
    if( i<0 || j<0 || i>=width || j>=height){
        return 1;
    }

    cells[i+j*width] = flag;
    return 0;
}

//create a new grid with arguments - width and height
//check the value of width and height, return 0 if there is invalid value
//otherwise, return a pointer to a new grid with all cells dead
char* createNewGrid(int w, int h){

    if( w<1 || h<1 ){
        return 0;
    }

    char *cell = (char*)calloc( w*h, sizeof(char));

    width = w;
    height = h;

    for(int j=0; j<height; j++)
        for(int i=0; i<width; i++)
            changeCell(cell, i, j, '0');

    return cell;
}

//count the number of alive cell around
//check grid, i, j, particularly when i, j pointing the border of the grid
int count(char *cells, int i, int j){
    if( i<0 || j<0 || i>=width || j>=height){
        return -1;
    }

    int count = 0;

    for(int k=j-1; k<=height && k<j+2; k++){
        if(k<0)
            continue;
        for(int n=i-1; n<=width && n<i+2; n++){
            if(n<0)
                continue;
            if(cells[n+k*width] == '1')
                count++;
        }
    }

    if(cells[i+j*width] == '1'){
        count--;
    }

    return count;
}

//change the whole grid according to the previous grid
//count 0-1 or 4-8, cell dead; count 3, cell live
char* changeGrid(char *preCells){
    char *curCells = createNewGrid(width, height);

    int number = 0;

    for(int j=0; j<height; j++){
        for(int i=0; i<width; i++){
            number = count(preCells, i, j);

            if((number==2 || number==3) && preCells[i+j*width]=='1'){
                changeCell(curCells, i, j, '1');
            }

            if(number==3 && preCells[i+j*width]=='0'){
                changeCell(curCells, i, j, '1');
            }
        }
    }

    return curCells;
}
